home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / etc / apparmor / rc.apparmor.functions < prev    next >
Encoding:
Text File  |  2009-04-08  |  12.9 KB  |  530 lines

  1. #!/bin/sh
  2. #
  3. #    $Id: rc.apparmor.functions 1280 2008-06-09 11:00:28Z jrjohansen $
  4. #
  5. # ----------------------------------------------------------------------
  6. #    Copyright (c) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
  7. #    NOVELL (All rights reserved)
  8. #
  9. #    This program is free software; you can redistribute it and/or
  10. #    modify it under the terms of version 2 of the GNU General Public
  11. #    License published by the Free Software Foundation.
  12. #
  13. #    This program is distributed in the hope that it will be useful,
  14. #    but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16. #    GNU General Public License for more details.
  17. #
  18. #    You should have received a copy of the GNU General Public License
  19. #    along with this program; if not, contact Novell, Inc.
  20. # ----------------------------------------------------------------------
  21. # rc.apparmor.functions by Steve Beattie
  22. #
  23. # NOTE: rc.apparmor initscripts that source this file need to implement
  24. # the following set of functions:
  25. #    aa_action
  26. #    aa_log_action_start
  27. #    aa_log_action_end
  28. #    aa_log_success_msg
  29. #    aa_log_warning_msg
  30. #    aa_log_failure_msg
  31. #    aa_log_skipped_msg
  32. #    aa_log_daemon_msg
  33. #    aa_log_end_msg
  34.  
  35. # Some nice defines that we use
  36.  
  37. CONFIG_DIR=/etc/apparmor
  38. MODULE=apparmor
  39. OLD_MODULE=subdomain
  40. if [ -f "${CONFIG_DIR}/${MODULE}.conf" ] ; then
  41.     APPARMOR_CONF="${CONFIG_DIR}/${MODULE}.conf"
  42. elif [ -f "${CONFIG_DIR}/${OLD_MODULE}.conf" ] ; then
  43.     APPARMOR_CONF="${CONFIG_DIR}/${OLD_MODULE}.conf"
  44. elif [ -f "/etc/immunix/subdomain.conf" ] ; then
  45.     aa_log_warning_msg "/etc/immunix/subdomain.conf is deprecated, use ${CONFIG_DIR}/subdomain.conf instead"
  46.     APPARMOR_CONF="/etc/immunix/subdomain.conf"
  47. elif [ -f "/etc/subdomain.conf" ] ; then
  48.     aa_log_warning_msg "/etc/subdomain.conf is deprecated, use ${CONFIG_DIR}/subdomain.conf instead"
  49.     APPARMOR_CONF="/etc/subdomain.conf"
  50. else
  51.     aa_log_warning_msg "Unable to find config file in ${CONFIG_DIR}, installation problem?"
  52. fi
  53.  
  54. # Read configuration options from /etc/subdomain.conf, default is to
  55. # warn if subdomain won't load.
  56. SUBDOMAIN_MODULE_PANIC="warn"
  57. SUBDOMAIN_ENABLE_OWLSM="no"
  58. APPARMOR_ENABLE_AAEVENTD="no"
  59.  
  60. if [ -f "${APPARMOR_CONF}" ] ; then
  61.     #parse the conf file to see what we should do
  62.     . "${APPARMOR_CONF}"
  63. fi
  64.  
  65. PARSER=/sbin/apparmor_parser
  66.  
  67. # SUBDOMAIN_DIR and APPARMOR_DIR might be defined in subdomain.conf|apparmor.conf
  68. if [ -d "${APPARMOR_DIR}" ] ; then
  69.     PROFILE_DIR=${APPARMOR_DIR}
  70. elif [ -d "${SUBDOMAIN_DIR}" ] ; then
  71.     PROFILE_DIR=${SUBDOMAIN_DIR}
  72. elif [ -d /etc/apparmor.d ] ; then
  73.     PROFILE_DIR=/etc/apparmor.d
  74. elif [ -d /etc/subdomain.d ] ; then
  75.     PROFILE_DIR=/etc/subdomain.d
  76. fi
  77. ABSTRACTIONS="-I${PROFILE_DIR}"
  78. AA_EV_BIN=/usr/sbin/aa-eventd
  79. AA_EV_PIDFILE=/var/run/aa-eventd.pid
  80. AA_STATUS=/usr/sbin/apparmor_status
  81. SD_EV_BIN=/usr/sbin/sd-event-dispatch.pl
  82. SD_EV_PIDFILE=/var/run/sd-event-dispatch.init.pid
  83. SD_STATUS=/usr/sbin/subdomain_status
  84. SECURITYFS=/sys/kernel/security
  85.  
  86. SUBDOMAINFS_MOUNTPOINT=$(grep subdomainfs /etc/fstab  | \
  87.     sed -e 's|^[[:space:]]*[^[:space:]]\+[[:space:]]\+\(/[^[:space:]]*\)[[:space:]]\+subdomainfs.*$|\1|' 2> /dev/null)
  88.  
  89. if [ -d "/var/lib/${MODULE}" ] ; then
  90.     APPARMOR_TMPDIR="/var/lib/${MODULE}"
  91. elif [ -d "/var/lib/${OLD_MODULE}" ] ; then
  92.     APPARMOR_TMPDIR="/var/lib/${OLD_MODULE}"
  93. else
  94.     APPARMOR_TMPDIR="/tmp"
  95. fi
  96.  
  97.  
  98. # keep exit status from parser during profile load.  0 is good, 1 is bad
  99. STATUS=0
  100.  
  101. # Test if the apparmor "module" is present.
  102. is_apparmor_present() {
  103.     local modules=$1
  104.     shift
  105.  
  106.     while [ $# -gt 0 ] ; do
  107.         modules="$modules|$1"
  108.         shift
  109.     done
  110.  
  111.     # check for subdomainfs version of module
  112.     grep -qE "^($modules)[[:space:]]" /proc/modules
  113.  
  114.     if [ $? -ne 0 ] ; then
  115.         ls /sys/module/apparmor 2>/dev/null | grep -qE "^($modules)" 
  116.     fi
  117.  
  118.     return $?
  119. }
  120.  
  121. # This set of patterns to skip needs to be kept in sync with
  122. # SubDomain.pm::isSkippableFile()
  123. # returns 0 if profile should NOT be skipped
  124. # returns 1 on verbose skip
  125. # returns 2 on silent skip
  126. skip_profile() {
  127.     local profile=$1
  128.     if [ "${profile%.rpmnew}" != "${profile}" -o \
  129.          "${profile%.rpmsave}" != "${profile}" -o \
  130.          -e "${PROFILE_DIR}/disable/`basename ${profile}`" -o \
  131.          "${profile%\~}" != "${profile}" ] ; then
  132.         return 1
  133.     fi
  134.     # Silently ignore the dpkg files
  135.     if [ "${profile%.dpkg-new}" != "${profile}" -o \
  136.          "${profile%.dpkg-old}" != "${profile}" -o \
  137.          "${profile%.dpkg-dist}" != "${profile}" ] ; then
  138.         return 2
  139.     fi
  140.  
  141.     return 0
  142. }
  143.  
  144. force_complain() {
  145.     local profile=$1
  146.  
  147.     # if profile not in complain mode
  148.     if ! egrep -q "^/.*[ \t]+flags[ \t]*=[ \t]*\([ \t]*complain[ \t]*\)[ \t]+{" $profile ; then
  149.         local link="${PROFILE_DIR}/force-complain/`basename ${profile}`"
  150.         if [ -e "$link" ] ; then
  151.             aa_log_warning_msg "found $link, forcing complain mode"
  152.             return 0
  153.         fi
  154.     fi
  155.  
  156.     return 1
  157. }
  158.  
  159. parse_profiles() {
  160.     # get parser arg
  161.     case "$1" in
  162.         load)
  163.             PARSER_ARGS="--add"
  164.             PARSER_MSG="Loading AppArmor profiles "
  165.             ;;
  166.         reload)
  167.             PARSER_ARGS="--replace"
  168.             PARSER_MSG="Reloading AppArmor profiles "
  169.             ;;
  170.         *)
  171.             aa_log_failure_msg "required 'load' or 'reload'"
  172.             exit 1
  173.             ;;
  174.     esac
  175.     aa_log_action_begin "$PARSER_MSG"
  176.     # run the parser on all of the apparmor profiles
  177.     if [ ! -f "$PARSER" ]; then
  178.         aa_log_failure_msg "AppArmor parser not found"
  179.         aa_log_action_end 1
  180.         exit 1
  181.     fi
  182.  
  183.     if [ ! -d "$PROFILE_DIR" ]; then
  184.         aa_log_failure_msg "Profile directory not found"
  185.         aa_log_action_end 1
  186.         exit 1
  187.     fi
  188.  
  189.     if [ -z "$(ls $PROFILE_DIR/)" ]; then
  190.         aa_log_failure_msg "No profiles found"
  191.         aa_log_action_end 1
  192.         return 1
  193.     fi
  194.  
  195.     for profile in $PROFILE_DIR/*; do
  196.         skip_profile "${profile}"
  197.         skip=$?
  198.         # Ignore skip status == 2 (silent skip)
  199.         if [ "$skip" -eq 1 ] ; then
  200.             aa_log_skipped_msg "$profile"
  201.             logger -t "AppArmor(init)" -p daemon.warn "Skipping profile $profile"
  202.             STATUS=2
  203.         elif [ "$skip" -ne 0 ]; then
  204.             continue
  205.         fi
  206.         if [ -f "${profile}" ] ; then
  207.             COMPLAIN=""
  208.             if force_complain "${profile}" ; then
  209.                 COMPLAIN="-C"
  210.             fi
  211.             $PARSER $ABSTRACTIONS $PARSER_ARGS $COMPLAIN "$profile" > /dev/null
  212.             if [ $? -ne 0 ]; then
  213.                 aa_log_failure_msg "$profile failed to load"
  214.                 STATUS=1
  215.             fi
  216.         fi
  217.     done
  218.     if [ $STATUS -eq 2 ]; then
  219.         STATUS=0
  220.     fi
  221.     aa_log_action_end "$STATUS"
  222.     return $STATUS
  223. }
  224.  
  225. profiles_names_list() {
  226.     # run the parser on all of the apparmor profiles
  227.     TMPFILE=$1
  228.     if [ ! -f "$PARSER" ]; then
  229.         aa_log_failure_msg "- AppArmor parser not found"
  230.         exit 1
  231.     fi
  232.  
  233.     if [ ! -d "$PROFILE_DIR" ]; then
  234.         aa_log_failure_msg "- Profile directory not found"
  235.         exit 1
  236.     fi
  237.  
  238.     for profile in $PROFILE_DIR/*; do
  239.             if skip_profile "${profile}" && [ -f "${profile}" ] ; then
  240.             LIST_ADD=$($PARSER $ABSTRACTIONS -N "$profile" | grep -v '\^')
  241.             if [ $? -eq 0 ]; then
  242.                 echo "$LIST_ADD" >>$TMPFILE
  243.             fi
  244.         fi
  245.     done
  246. }
  247.  
  248. failstop_system() {
  249.     level=$(runlevel | cut -d" " -f2)
  250.     if [ $level -ne "1" ] ; then
  251.         aa_log_failure_msg "- could not start AppArmor.  Changing to runlevel 1"
  252.         telinit 1;
  253.         return -1;
  254.     fi
  255.     aa_log_failure_msg "- could not start AppArmor."
  256.     return -1
  257. }
  258.  
  259. module_panic() {
  260.     # the module failed to load, determine what action should be taken
  261.  
  262.     case "$SUBDOMAIN_MODULE_PANIC" in
  263.         "warn"|"WARN")
  264.             return 1 ;;
  265.         "panic"|"PANIC") failstop_system
  266.             rc=$?
  267.             return $rc ;;
  268.         *) aa_log_failure_msg "- invalid AppArmor module fail option"
  269.             return -1 ;;
  270.     esac
  271. }
  272.  
  273. is_apparmor_loaded() {
  274.     if ! is_securityfs_mounted ; then
  275.         mount_securityfs
  276.     fi
  277.  
  278.     mount_subdomainfs
  279.  
  280.     if [ -f "${SECURITYFS}/${MODULE}/profiles" ]; then
  281.         SFS_MOUNTPOINT="${SECURITYFS}/${MODULE}"
  282.         return 0
  283.     fi
  284.  
  285.     if [ -f "${SECURITYFS}/${OLD_MODULE}/profiles" ]; then
  286.         SFS_MOUNTPOINT="${SECURITYFS}/${OLD_MODULE}"
  287.         return 0
  288.     fi
  289.  
  290.     if [ -f "${SUBDOMAINFS_MOUNTPOINT}/profiles" ]; then
  291.         SFS_MOUNTPOINT=${SUBDOMAINFS_MOUNTPOINT}
  292.         return 0
  293.     fi
  294.  
  295.     # check for subdomainfs version of module
  296.     is_apparmor_present apparmor subdomain
  297.  
  298.     return $?
  299. }
  300.  
  301. is_securityfs_mounted() {
  302.     grep -q securityfs /proc/filesystems && grep -q securityfs /proc/mounts
  303.     return $?
  304. }
  305.  
  306. mount_securityfs() {
  307.     if grep -q securityfs /proc/filesystems ; then
  308.         aa_action "Mounting securityfs on ${SECURITYFS}" \
  309.                 mount -t securityfs securityfs "${SECURITYFS}"
  310.         return $?
  311.     fi
  312.     return 0
  313. }
  314.  
  315.  
  316. mount_subdomainfs() {
  317.     # for backwords compatibility
  318.     if grep -q subdomainfs /proc/filesystems && \
  319.        ! grep -q subdomainfs /proc/mounts && \
  320.        [ -n "${SUBDOMAINFS_MOUNTPOINT}" ]; then
  321.         aa_action "Mounting subdomainfs on ${SUBDOMAINFS_MOUNTPOINT}" \
  322.                 mount "${SUBDOMAINFS_MOUNTPOINT}"
  323.         return $?
  324.     fi
  325.     return 0
  326. }
  327.  
  328. unmount_subdomainfs() {
  329.     SUBDOMAINFS=$(grep subdomainfs /proc/mounts  | cut -d" " -f2 2> /dev/null)
  330.     if [ -n "${SUBDOMAINFS}" ]; then
  331.         aa_action "Unmounting subdomainfs" umount ${SUBDOMAINFS}
  332.     fi
  333. }
  334.  
  335. load_module() {
  336.     local rc=0
  337.     if modinfo -F filename apparmor > /dev/null 2>&1 ; then
  338.         MODULE=apparmor
  339.     elif modinfo -F filename ${OLD_MODULE} > /dev/null 2>&1 ; then
  340.         MODULE=${OLD_MODULE}
  341.     fi
  342.  
  343.     if ! is_apparmor_present apparmor subdomain ; then
  344.         aa_action "Loading AppArmor module" /sbin/modprobe -q $MODULE $1
  345.         rc=$?
  346.         if [ $rc -ne 0 ] ; then
  347.             module_panic
  348.             rc=$?
  349.             if [ $rc -ne 0 ] ; then
  350.                 exit $rc
  351.             fi
  352.         fi
  353.     fi
  354.  
  355.     if ! is_apparmor_loaded ; then
  356.         return 1
  357.     fi
  358.  
  359.     return $rc
  360. }
  361.  
  362. apparmor_start() {
  363.     aa_log_daemon_msg "Starting AppArmor"
  364.     if ! is_apparmor_loaded ; then
  365.         load_module
  366.         rc=$?
  367.         if [ $rc -ne 0 ] ; then
  368.             aa_log_end_msg $rc
  369.             return $rc
  370.         fi
  371.     fi
  372.  
  373.     if [ ! -w "$SFS_MOUNTPOINT/.load" ] ; then
  374.         aa_log_failure_msg "Loading AppArmor profiles - failed, Do you have the correct privileges?"
  375.         aa_log_end_msg 1
  376.         return 1
  377.     fi
  378.  
  379.     configure_owlsm
  380.  
  381.     if [ $(wc -l "$SFS_MOUNTPOINT/profiles" | awk '{print $1}') -eq 0 ] ; then
  382.         parse_profiles load
  383.     else
  384.         aa_log_skipped_msg "AppArmor already loaded with profiles."
  385.     fi
  386.     aa_log_end_msg 0
  387.     return 0
  388. }
  389.  
  390. remove_profiles() {
  391.  
  392.     # removing profiles as we directly read from subdomainfs
  393.     # doesn't work, since we are removing entries which screws up
  394.     # our position.  Lets hope there are never enough profiles to
  395.     # overflow the variable
  396.     if ! is_apparmor_loaded ; then
  397.         aa_log_failure_msg "AppArmor module is not loaded"
  398.         return 1
  399.     fi
  400.  
  401.     if [ ! -w "$SFS_MOUNTPOINT/.remove" ] ; then
  402.         aa_log_failure_msg "Root privileges not available"
  403.         return 1
  404.     fi
  405.  
  406.     if [ ! -x "${PARSER}" ] ; then
  407.         aa_log_failure_msg "Unable to execute AppArmor parser"
  408.         return 1
  409.     fi
  410.  
  411.     retval=0
  412.     #the list of profiles isn't stable once we start adding or removing
  413.     #them so stor to tmp first
  414.     MODULE_PLIST=$(mktemp ${APPARMOR_TMPDIR}/tmp.XXXXXXXX)
  415.     sed -e "s/ (\(enforce\|complain\))$//" "$SFS_MOUNTPOINT/profiles" | sort >"$MODULE_PLIST"
  416.     cat "$MODULE_PLIST" | while read profile ; do
  417.         echo -n "$profile" > "$SFS_MOUNTPOINT/.remove"
  418.         rc=$?
  419.         if [ ${rc} -ne 0 ] ; then 
  420.             retval=${rc}
  421.         fi
  422.     done
  423.     rm "$MODULE_PLIST"
  424.     return ${retval}
  425. }
  426.  
  427. apparmor_stop() {
  428.     aa_log_daemon_msg "Unloading AppArmor profiles "
  429.     remove_profiles
  430.     rc=$?
  431.     log_end_msg $rc
  432.     return $rc
  433. }
  434.  
  435. apparmor_kill() {
  436.     aa_log_daemon_msg "Unloading AppArmor modules "
  437.     if ! is_apparmor_loaded ; then
  438.         aa_log_failure_msg "AppArmor module is not loaded"
  439.         return 1
  440.     fi
  441.  
  442.     unmount_subdomainfs
  443.     if is_apparmor_present apparmor ; then
  444.         MODULE=apparmor
  445.     elif is_apparmor_present subdomain ; then
  446.         MODULE=subdomain
  447.     else
  448.         aa_log_failure_msg "AppArmor is builtin"
  449.         return 1
  450.     fi
  451.     /sbin/modprobe -qr $MODULE
  452.     rc=$?
  453.     aa_log_end_msg $rc
  454.     return $rc
  455. }
  456.  
  457. __apparmor_restart() {
  458.     if [ ! -w "$SFS_MOUNTPOINT/.load" ] ; then
  459.         aa_log_failure_msg "Loading AppArmor profiles - failed, Do you have the correct privileges?"
  460.         return 4
  461.     fi
  462.  
  463.     configure_owlsm
  464.     parse_profiles reload
  465.     PNAMES_LIST=$(mktemp ${APPARMOR_TMPDIR}/tmp.XXXXXXXX)
  466.     profiles_names_list ${PNAMES_LIST}
  467.     MODULE_PLIST=$(mktemp ${APPARMOR_TMPDIR}/tmp.XXXXXXXX)
  468.     sed  -e "s/ (\(enforce\|complain\))$//" "$SFS_MOUNTPOINT/profiles" | sort >"$MODULE_PLIST"
  469.     sort "$PNAMES_LIST" | comm -2 -3 "$MODULE_PLIST" - | while read profile ; do
  470.         echo -n "$profile" > "$SFS_MOUNTPOINT/.remove"
  471.     done
  472.     rm "$MODULE_PLIST"
  473.     rm "$PNAMES_LIST"
  474.     return 0
  475. }
  476.  
  477. apparmor_restart() {
  478.     if ! is_apparmor_loaded ; then
  479.         apparmor_start
  480.         rc=$?
  481.         return $rc
  482.     fi
  483.  
  484.     __apparmor_restart
  485.     return $?
  486. }
  487.  
  488. apparmor_try_restart() {
  489.     if ! is_apparmor_loaded ; then
  490.         return 0
  491.     fi
  492.  
  493.     __apparmor_restart
  494.     return $?
  495. }
  496.  
  497. configure_owlsm () {
  498.     if [ "${SUBDOMAIN_ENABLE_OWLSM}" = "yes" -a -f ${SFS_MOUNTPOINT}/control/owlsm ] ; then
  499.         # Sigh, the "sh -c" is necessary for the SuSE aa_action
  500.         # and it can't be abstracted out as a seperate function, as
  501.         # that breaks under RedHat's action, which needs a
  502.         # binary to invoke.
  503.         aa_action "Enabling OWLSM extension" sh -c "echo -n \"1\" > \"${SFS_MOUNTPOINT}/control/owlsm\""
  504.     elif [ -f "${SFS_MOUNTPOINT}/control/owlsm" ] ; then
  505.         aa_action "Disabling OWLSM extension" sh -c "echo -n \"0\" > \"${SFS_MOUNTPOINT}/control/owlsm\""
  506.     fi
  507. }
  508.  
  509. apparmor_status () {
  510.     if test -x ${AA_STATUS} ; then
  511.         ${AA_STATUS} --verbose
  512.         return $?
  513.     fi
  514.     if test -x ${SD_STATUS} ; then
  515.         ${SD_STATUS} --verbose
  516.         return $?
  517.     fi
  518.     if ! is_apparmor_present apparmor subdomain ; then
  519.         echo "AppArmor is not loaded."
  520.         rc=1
  521.     else
  522.         echo "AppArmor is enabled,"
  523.         rc=0
  524.     fi
  525.     echo "Install the apparmor-utils package to receive more detailed"
  526.     echo "status information here (or examine ${SFS_MOUNTPOINT} directly)."
  527.  
  528.     return $rc
  529. }
  530.